package bhwz.seac3.ui.user;

import java.awt.Color;
import java.awt.Font;
import java.awt.SystemColor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;

import bhwz.seac3.LocalBLServiceManager;
import bhwz.seac3.RMIClientBLServiceManager;
import bhwz.seac3.blservice.AutoRedisplay;
import bhwz.seac3.blservice.query.PlayerQueryBLService;
import bhwz.seac3.ui.user.DetailsListenerFactory.Type;
import bhwz.seac3.util.ListSorter.SortOrder;
import bhwz.seac3.util.SortableTable;
import bhwz.seac3.util.SortableTableModel;
import bhwz.seac3.vo.PlayerVo;

import java.awt.BorderLayout;

public class PlayerDataPanel extends JPanel implements AutoRedisplay {

	private static final long serialVersionUID = 2722547600290062597L;

	private SeasonSelectComboBox seasonSelectComboBox;
	private JComboBox<String> comboBox位置;
	private JComboBox<String> comboBox赛区;
	private DoubleComboBox comboBox两双1;
	private DoubleComboBox comboBox两双2;
	private JComboBox<String> comboBoxSort;
	private JComboBox<String> comboBoxSortOrder;
	private SortableTable table;
	private JScrollPane tablePane;
	private Object[][] info;
	private String columns[] = { "姓名", "球队", "得分", "助攻", "篮板", "抢断",
			"盖帽", "得分" };
	private final Vector<String> sortColumns = new Vector<String>(
			Arrays.asList(new String[] { "球员名称", "所属球队", "参赛场数", "先发场数", "篮板数",
					"助攻数", "在场时间", "投篮命中率", "三分命中率", "罚球命中率", "进攻数", "防守数",
					"抢断数", "盖帽数", "失误数", "犯规数", "得分", "效率", "GmSc效率值", "真实命中率",
					"投篮效率", "篮板率", "进攻篮板率", "防守篮板率", "助攻率", "抢断率", "盖帽率",
					"失误率", "使用率", "两双" }));
	private final ArrayList<Function<PlayerVo, Comparable<?>>> sortMethods = new ArrayList<Function<PlayerVo, Comparable<?>>>() {

		private static final long serialVersionUID = 1L;

		{
			this.add(vo -> vo.getName());
			this.add(vo -> vo.get所属球队());
			this.add(vo -> vo.get比赛场数());
			this.add(vo -> vo.get先发场数());
			this.add(vo -> vo.get篮板数());
			this.add(vo -> vo.get助攻数());
			this.add(vo -> vo.get在场时间());
			this.add(vo -> vo.get命中率());
			this.add(vo -> vo.get三分命中率());
			this.add(vo -> vo.get罚球命中率());
			this.add(vo -> vo.get前场篮板数());
			this.add(vo -> vo.get后场篮板数());
			this.add(vo -> vo.get断球数());
			this.add(vo -> vo.get盖帽数());
			this.add(vo -> vo.get失误数());
			this.add(vo -> vo.get犯规数());
			this.add(vo -> vo.get比赛得分());
			this.add(vo -> vo.get效率());
			this.add(vo -> vo.getGmSc效率值());
			this.add(vo -> vo.get真实投篮命中率());
			this.add(vo -> vo.get投篮效率());
			this.add(vo -> vo.get篮板率());
			this.add(vo -> vo.get进攻篮板率());
			this.add(vo -> vo.get防守篮板率());
			this.add(vo -> vo.get助攻率());
			this.add(vo -> vo.get抢断率());
			this.add(vo -> vo.get盖帽率());
			this.add(vo -> vo.get失误率());
			this.add(vo -> vo.get使用率());
			this.add(vo -> getDouble(vo));
		}
	};
	private final String[] sortOrder = new String[] { "降序", "升序" };

	private class DoubleComboBox extends JComboBox<String> {

		private static final long serialVersionUID = -5141427189730626483L;
		private final String[] items = { "得分", "篮板数", "助攻数", "抢断数", "盖帽数" };

		DoubleComboBox() {
			super();
			this.setModel(new DefaultComboBoxModel<String>(items));
			this.addActionListener(e->{
				comboBoxSort.setSelectedItem("两双");
			});
			
		}
	}

	public PlayerDataPanel() {
		super();

		setLayout(new BorderLayout(0, 0));

		JPanel panel = new JPanel();
		panel.setBackground(SystemColor.textHighlight);
		add(panel, BorderLayout.NORTH);

		seasonSelectComboBox = new SeasonSelectComboBox();
		seasonSelectComboBox.setFont(new Font("微软雅黑", Font.PLAIN, 15));
		panel.add(seasonSelectComboBox);

		JLabel lblNewLabel = new JLabel("\u8D5B\u5B63");
		panel.add(lblNewLabel);
		lblNewLabel.setForeground(SystemColor.window);
		lblNewLabel.setFont(new Font("华文楷体", Font.BOLD, 18));

		JButton averageButton = new JButton("场均");
		panel.add(averageButton);
		averageButton.setFocusPainted(false);
		averageButton.setFont(new Font("华文楷体", Font.BOLD, 16));
		averageButton.addActionListener(e -> display场均数据(seasonSelectComboBox
				.getSeason()));

		JButton totalButton = new JButton("\u8D5B\u5B63");
		panel.add(totalButton);
		totalButton.setFocusPainted(false);
		totalButton.setFont(new Font("华文楷体", Font.BOLD, 16));

		totalButton.addActionListener(e -> display总数据(seasonSelectComboBox
				.getSeason()));

		comboBox两双1 = new DoubleComboBox();
		comboBox两双1.addActionListener(e -> redisplay());
		comboBox两双1.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		comboBox两双1.setBackground(Color.WHITE);
		panel.add(comboBox两双1);

		comboBox两双2 = new DoubleComboBox();
		comboBox两双2.addActionListener(e -> redisplay());
		comboBox两双2.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		comboBox两双2.setBackground(Color.WHITE);
		panel.add(comboBox两双2);

		JLabel lblNewLabel1 = new JLabel("排序");
		panel.add(lblNewLabel1);
		lblNewLabel1.setForeground(SystemColor.window);
		lblNewLabel1.setFont(new Font("华文楷体", Font.BOLD, 18));

		comboBoxSort = new JComboBox<String>();
		comboBoxSort.setModel(new DefaultComboBoxModel<String>(sortColumns));
		comboBoxSort.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		comboBoxSort.setBackground(Color.WHITE);
		comboBoxSort.setSelectedItem("得分");
		comboBoxSort.addActionListener(e -> redisplay());
		panel.add(comboBoxSort);

		comboBoxSortOrder = new JComboBox<String>();
		comboBoxSortOrder.addActionListener(e -> redisplay());
		comboBoxSortOrder.setModel(new DefaultComboBoxModel<String>(sortOrder));
		comboBoxSortOrder.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		comboBoxSortOrder.setBackground(Color.WHITE);
		panel.add(comboBoxSortOrder);

		try {
			info = playerToArray(((PlayerQueryBLService) RMIClientBLServiceManager
					.getBLService(PlayerQueryBLService.class))
					.query场均数据(seasonSelectComboBox.getSeason()));
		} catch (Exception e1) {
			JOptionPane
					.showMessageDialog(this, "服务器连接发生异常\n" + e1.getMessage());
			e1.printStackTrace();
		}
		TableModel model = new SortableTableModel(info, columns);

		JPanel panel_1 = new JPanel();
		add(panel_1, BorderLayout.CENTER);
		table = new SortableTable(model);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
		addPlayerDetailsListener();
		panel_1.setLayout(new BorderLayout(0, 0));

		tablePane = new JScrollPane(table);
		panel_1.add(tablePane, BorderLayout.CENTER);

		JPanel panel_2 = new JPanel();
		panel_2.setBackground(SystemColor.textHighlight);
		panel_1.add(panel_2, BorderLayout.NORTH);

		JLabel label = new JLabel("\u7403\u5458\u4F4D\u7F6E");
		panel_2.add(label);
		label.setForeground(Color.WHITE);
		label.setFont(new Font("华文楷体", Font.BOLD, 18));

		comboBox位置 = new JComboBox<String>();
		panel_2.add(comboBox位置);
		comboBox位置.setModel(new DefaultComboBoxModel<String>(new String[] {
				"全部", "前锋", "中锋", "后卫" }));
		comboBox位置.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		comboBox位置.setBackground(Color.WHITE);
		comboBox位置.addActionListener(e -> {
			switch ((String) comboBox位置.getSelectedItem()) {
			case "前锋":
				filters.put("位置", o -> o.stream().filter(vo -> {
					if (vo.getPosition() == null)
						return false;
					else
						return vo.getPosition().contains("F");
				}).collect(Collectors.toList()));
				break;
			case "中锋":
				filters.put("位置", o -> o.stream().filter(vo -> {
					if (vo.getPosition() == null)
						return false;
					else
						return vo.getPosition().contains("C");
				}).collect(Collectors.toList()));
				break;
			case "后卫":
				filters.put("位置", o -> o.stream().filter(vo -> {
					if (vo.getPosition() == null)
						return false;
					else
						return vo.getPosition().contains("G");
				}).collect(Collectors.toList()));
				break;
			default:
				filters.put("位置", o -> o);
				break;
			}
			redisplay();
		});

		JLabel label_1 = new JLabel("\u8D5B\u533A");
		panel_2.add(label_1);
		label_1.setForeground(Color.WHITE);
		label_1.setFont(new Font("华文楷体", Font.BOLD, 18));

		comboBox赛区 = new JComboBox<String>();
		panel_2.add(comboBox赛区);
		comboBox赛区.setModel(new DefaultComboBoxModel<String>(new String[] {
				"全部", "东部", "西部", "东部-东南分区", "东部-中央分区", "东部-大西洋分区", "西部-太平洋分区",
				"西部-西北分区", "西部-西南分区" }));
		comboBox赛区.setFont(new Font("微软雅黑", Font.PLAIN, 13));
		comboBox赛区
				.addActionListener(e -> {
					switch ((String) comboBox赛区.getSelectedItem()) {
					case "东部":
						filters.put(
								"赛区",
								o -> o.stream()
										.filter(vo -> {
											return "Southeast".equals(vo
													.get所属联盟())
													|| "Central".equals(vo
															.get所属联盟())
													|| "Atlantic".equals(vo
															.get所属联盟());
										}).collect(Collectors.toList()));
						break;
					case "西部":
						filters.put(
								"赛区",
								o -> o.stream()
										.filter(vo -> {
											return "Pacific".equals(vo
													.get所属联盟())
													|| "Northwest".equals(vo
															.get所属联盟())
													|| "Southwest".equals(vo
															.get所属联盟());
										}).collect(Collectors.toList()));
						break;
					case "东部-东南分区":
						filters.put("赛区", o -> o.stream().filter(vo -> {
							return "Southeast".equals(vo.get所属联盟());
						}).collect(Collectors.toList()));
						break;
					case "东部-中央分区":
						filters.put("赛区", o -> o.stream().filter(vo -> {
							return "Central".equals(vo.get所属联盟());
						}).collect(Collectors.toList()));
						break;
					case "东部-大西洋分区":
						filters.put("赛区", o -> o.stream().filter(vo -> {
							return "Atlantic".equals(vo.get所属联盟());
						}).collect(Collectors.toList()));
						break;
					case "西部-太平洋分区":
						filters.put("赛区", o -> o.stream().filter(vo -> {
							return "Pacific".equals(vo.get所属联盟());
						}).collect(Collectors.toList()));
						break;
					case "西部-西北分区":
						filters.put("赛区", o -> o.stream().filter(vo -> {
							return "Northwest".equals(vo.get所属联盟());
						}).collect(Collectors.toList()));
						break;
					case "西部-西南分区":
						filters.put("赛区", o -> o.stream().filter(vo -> {
							return "Southwest".equals(vo.get所属联盟());
						}).collect(Collectors.toList()));
						break;
					default:
						filters.put("赛区", o -> o);
						break;
					}
					redisplay();
				});
		comboBox赛区.setBackground(Color.WHITE);

		JLabel label_3 = new JLabel("\u4E24\u53CC\uFF1A");
		panel_2.add(label_3);
		label_3.setForeground(Color.WHITE);
		label_3.setFont(new Font("华文楷体", Font.BOLD, 18));

		panel_2.add(comboBox两双1);
		panel_2.add(comboBox两双2);

		LocalBLServiceManager.getRedisplayControllerBLService().register(this);
	}

	private void addPlayerDetailsListener() {
		switch (显示的数据) {
		case "总数据":
			table.addDoubleClickOnDataListener(DetailsListenerFactory
					.getPlayerDetailListener(Type.ALL,
							seasonSelectComboBox.getSeason()), 0);
			break;
		case "场均数据":
			table.addDoubleClickOnDataListener(DetailsListenerFactory
					.getPlayerDetailListener(Type.AVG,
							seasonSelectComboBox.getSeason()), 0);
			break;
		}
	}

	private String 显示的数据 = "总数据";

	@Override
	public void redisplay() {
		setSortHead((String)comboBoxSort.getSelectedItem());
		if (显示的数据.equals("总数据")) {
			display总数据(seasonSelectComboBox.getSeason());
		}
		if (显示的数据.equals("场均数据")) {
			display场均数据(seasonSelectComboBox.getSeason());
		}
	}

	public void display场均数据(String season) {
		displayData(season,
				() -> ((PlayerQueryBLService) RMIClientBLServiceManager
						.getBLService(PlayerQueryBLService.class)).query场均数据(
						season, getSortMethod(), getSortOrder()));
		显示的数据 = "场均数据";
	}

	public void display总数据(String season) {
		displayData(season,
				() -> ((PlayerQueryBLService) RMIClientBLServiceManager
						.getBLService(PlayerQueryBLService.class)).query赛季总数据(
						season, getSortMethod(), getSortOrder()));
		显示的数据 = "总数据";
	}

	private interface Supplier {
		List<PlayerVo> get() throws Exception;
	}

	private Map<String, Function<List<PlayerVo>, List<PlayerVo>>> filters = new HashMap<>();

	@SuppressWarnings("unchecked")
	private void displayData(String season, Supplier supplier) {
		try {
			List<PlayerVo> data = supplier.get();

			// 过滤
			List<?>[] filteredData = { data };
			filters.forEach((name, filter) -> {
				List<?> filteList=filteredData[0];
				List<?> result = filter
						.apply((List<PlayerVo>) filteList);
				System.out.println(name+":"+result.size());
				filteredData[0]=result;
			});

			info = playerToArray((List<PlayerVo>) filteredData[0]);
			table = new SortableTable(new SortableTableModel(info, columns));
			addPlayerDetailsListener();
			tablePane.setViewportView(table);
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, "服务器连接发生异常\n" + e.getMessage());
			e.printStackTrace();
		}
	}

	public Object[][] playerToArray(List<PlayerVo> lt) {
		int length = lt.size();
		Object[][] info = new Object[length][20];
		for (int n = 0; n < length; n++) {
			info[n][0] = lt.get(n).getName();
			info[n][1] = lt.get(n).get所属球队();
			info[n][2] = lt.get(n).get比赛得分();
			info[n][3] = lt.get(n).get助攻数();
			info[n][4] = lt.get(n).get篮板数();
			info[n][5] = lt.get(n).get断球数();
			info[n][6] = lt.get(n).get盖帽数();
			info[n][7] = getSortColumnData(lt.get(n));
		}
		return info;

	}

	private Comparable<?> getSortColumnData(PlayerVo vo) {
		return getSortMethod().apply(vo);
	}

	private double getDouble(PlayerVo vo) {
		return ((double) sortMethods.get(
				sortColumns.indexOf(comboBox两双1.getSelectedItem())).apply(vo))
				+ ((double) sortMethods.get(
						sortColumns.indexOf(comboBox两双2.getSelectedItem()))
						.apply(vo));
	}

	private Function<PlayerVo, Comparable<?>> getSortMethod() {
		return sortMethods.get(sortColumns.indexOf(comboBoxSort
				.getSelectedItem()));
	}

	private SortOrder getSortOrder() {
		if (comboBoxSortOrder.getSelectedItem().equals("升序"))
			return SortOrder.ESC;
		else
			return SortOrder.DESC;
	}
	
	private void setSortHead(String name){
		columns[7]=(String) comboBoxSort.getSelectedItem();
	}

}
